home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mgr / sparcmgr / src.zoo / src / subs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-09  |  16.2 KB  |  687 lines

  1. /*                        Copyright (c) 1987 Bellcore
  2.  *                            All Rights Reserved
  3.  *       Permission is granted to copy or use this program, EXCEPT that it
  4.  *       may not be sold for profit, the copyright notice must be reproduced
  5.  *       on copies, and credit should be given to Bellcore where it is due.
  6.  *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
  7.  */
  8. /*    $Header: subs.c,v 1.1 89/03/17 08:21:22 sau Exp $
  9.     $Source: /m1/mgr.new/src/RCS/subs.c,v $
  10. */
  11. static char    RCSid_[] = "$Source: /m1/mgr.new/src/RCS/subs.c,v $$Revision: 1.1 $";
  12.  
  13. /* misc window and screen mangement routines */
  14.  
  15. #include "bitmap.h"
  16. #include <stdio.h>
  17. #include <sys/ioctl.h>
  18. #include <sys/signal.h>
  19. #include "font.h"
  20. #include "defs.h"
  21. #include "event.h"
  22. #include "window.h"
  23.  
  24. /*****************************************************************************
  25.  *    deactivate all windows covered by win (used for new window creation)
  26.  */
  27.  
  28. set_covered(check)
  29. register WINDOW *check;            /* window to check covering against */
  30.    {
  31.    register WINDOW *win;
  32.  
  33.    for(win=active;win != (WINDOW *) 0;win=win->next)
  34.        if (win!=check && intersect(win,check) && W(flags)&W_ACTIVE) {
  35.           save_win(win);
  36.           do_event(EVENT_COVERED,win,E_MAIN);
  37.           W(flags) &= ~W_ACTIVE;
  38.           if (!(W(flags)&W_LOOK))
  39.              mask &= ~(1<<W(to_fd));
  40. #ifdef DEBUG
  41.           dprintf(o)(stderr,"\t%s covers %s\r\n",check->tty,W(tty));
  42. #endif
  43.           } 
  44.    }
  45.  
  46. /*****************************************************************************
  47.  *    find and activate all windows previously covered by win
  48.  */
  49.  
  50. un_covered()
  51.    {
  52.    register WINDOW *win,*check;
  53.    register int cover;
  54.    
  55.    for(win=active;win != (WINDOW *) 0;win=W(next)) {
  56. #ifdef DEBUG
  57.       dprintf(U)(stderr,"    invalidate cliplist: %s)\r\n",W(tty));
  58.       dprintf(o)(stderr,"    un_cover: %s)\n",W(tty));
  59. #endif
  60.       for(cover=0,check=active;check!=win && cover==0;check=check->next)
  61.          if (intersect(win,check)) cover=1;
  62.  
  63.       if (cover && W(flags)&W_ACTIVE) {
  64.           do_event(EVENT_COVERED,win,E_MAIN);
  65.           W(flags) &= ~W_ACTIVE;
  66.           if (!(W(flags)&W_LOOK))
  67.              mask &= ~(1<<W(to_fd));
  68. #ifdef DEBUG
  69.           dprintf(o)(stderr,"becoming inactive (covered by %s)\r\n",check->tty);
  70. #endif
  71.           }
  72.       else if (!cover && !(W(flags)&W_ACTIVE)) {
  73.           do_event(EVENT_UNCOVERED,win,E_MAIN);
  74.           W(flags) |= W_ACTIVE;
  75.           if (!(W(flags)&W_DIED))
  76.              mask |= (1<<W(to_fd));
  77. #ifdef DEBUG
  78.           dprintf(o)(stderr,"becoming active\r\n");
  79. #endif
  80.           }
  81.       else if (cover && !(W(flags)&W_ACTIVE))  {
  82. #ifdef DEBUG
  83.          dprintf(o)(stderr,"remains inactive (covered by %s)\r\n",check->tty);
  84. #endif
  85.          ;
  86.          }
  87.       else if (!cover && W(flags)&W_ACTIVE) {
  88. #ifdef DEBUG
  89.          dprintf(o)(stderr,"remains active\r\n");
  90. #endif
  91.          ;
  92.          }
  93.       else 
  94.          if( debug )
  95.         fprintf(stderr,"%s: unknown covering state\r\n",W(tty));
  96.       }
  97.    }
  98.  
  99. /*****************************************************************************
  100.  *    bring a window to the top
  101.  */
  102.  
  103. expose(win)
  104. register WINDOW *win;            /* window to expose */
  105.    {
  106. #ifdef DEBUG
  107.    dprintf(o)(stderr,"exposing %s\r\n",W(tty));
  108. #endif
  109.    
  110.    /* reorder windows */
  111.  
  112.    if (win == active)
  113.       return(0);
  114.  
  115.    W(prev)->next = W(next);
  116.    if (W(next))
  117.       W(next)->prev = W(prev);
  118.    else
  119.       ACTIVE(prev) = W(prev);
  120.  
  121.    W(prev) = ACTIVE(prev);
  122.    W(next) = active;
  123.  
  124.    ACTIVE(prev) = win;
  125.    active = win;
  126.  
  127.    if (!(W(flags)&W_ACTIVE)) {
  128.       for(win=active->next;win!=(WINDOW *) 0;win=W(next))
  129.          if (W(flags)&W_ACTIVE && intersect(active,win))
  130.             save_win(win);
  131.    
  132.       restore_win(active);
  133.    
  134.       clip_bad(active);    /* invalidate clip lists */
  135.       un_covered();
  136.       }
  137. #ifdef DEBUG
  138.    else
  139.       dprintf(o)(stderr,"expose: %s already active (0%o)\r\n",
  140.               ACTIVE(tty),ACTIVE(flags));
  141. #endif
  142.    }
  143.    
  144.    
  145. /*****************************************************************************
  146.  *    move a window at the bottom of window list
  147.  */
  148.  
  149. int
  150. bury(win)
  151. register WINDOW *win;            /* window to bury */
  152.    {
  153. #ifdef DEBUG
  154.    dprintf(o)(stderr,"burying %s\r\n",W(tty));
  155. #endif
  156.    if (!win || !W(next))
  157.       return(0);
  158.  
  159.    if (win == active)
  160.       active = W(next);
  161.  
  162.    W(prev)->next = W(next);
  163.    W(next)->prev = W(prev);
  164.  
  165.    W(prev) = ACTIVE(prev);
  166.    ACTIVE(prev)->next = win;
  167.  
  168.    ACTIVE(prev) = win;
  169.    W(next) = (WINDOW *) 0;
  170.    return(1);
  171.    }
  172.  
  173. /*****************************************************************************
  174.  *    bury a window at the bottom of the screen
  175.  */
  176.  
  177. hide(win)
  178. register WINDOW *win;            /* window to hide */
  179.    {
  180. #ifdef DEBUG
  181.    dprintf(o)(stderr,"hiding %s\r\n",W(tty));
  182. #endif
  183.    if (bury(win)==0)
  184.       return(0);
  185.    save_win(win);
  186.    repair(win);
  187.    clip_bad(active);    /* invalidate clip lists */
  188.    }
  189.  
  190. /*****************************************************************************
  191.  *    repair effects of buried window
  192.  */
  193.  
  194. int
  195. repair(clip)
  196. register WINDOW *clip;            /* window causing repairs */
  197.    {
  198.    register WINDOW *win;
  199. #ifdef NOCLIP
  200.    for(win=ACTIVE(prev)->prev;win!=active;win=W(prev))
  201.       if (!alone(win)) restore_win(win);
  202.    restore_win(win);
  203. #else
  204.    for(win=clip->prev;win!=active;win=W(prev))
  205.        if (intersect(clip,win))
  206.           clip_win(win,clip);
  207.     if (clip!= active && intersect(clip,active))
  208.        clip_win(active,clip);
  209. #endif
  210.    un_covered();
  211.    }
  212.    
  213. /*****************************************************************************
  214.  *    save a pixel image of the window
  215.  */
  216.  
  217. save_win(win)
  218. register WINDOW *win;            /* window to save */
  219.    {
  220. #ifdef DEBUG
  221.    dprintf(o)(stderr,"\t\t  saving %s\r\n",W(tty));
  222. #endif
  223.    if (W(save) == (BITMAP *) 0) {
  224.       W(save) = bit_alloc(BIT_WIDE(W(border)),BIT_HIGH(W(border)),
  225.                           NULL_DATA,DEPTH);
  226.       }
  227.    else if (BIT_WIDE(W(save)) != BIT_WIDE(W(border))  ||
  228.             BIT_HIGH(W(save)) != BIT_HIGH(W(border))) {
  229. #ifdef DEBUG
  230.       dprintf(o)(stderr,"Saved window %s mismatch\r\n",W(tty));
  231. #endif
  232.       bit_destroy(W(save));
  233.       W(save) = bit_alloc(BIT_WIDE(W(border)),BIT_HIGH(W(border)),
  234.                           NULL_DATA,DEPTH);
  235.       }
  236.  
  237.    bit_blit(W(save),0,0,BIT_WIDE(W(border)),BIT_HIGH(W(border)),
  238.           BIT_SRC,W(border),0,0);
  239.    }
  240.  
  241. /*****************************************************************************
  242.  *    partially restore a previously saved pixel image of the window 
  243.  */
  244.  
  245. #define C(x)    (clip->x)
  246. #ifndef Max
  247. #define Max(x,y)        ((x)>(y)?(x):(y))
  248. #endif
  249. #ifndef Min
  250. #define Min(x,y)        ((x)>(y)?(y):(x))
  251. #endif
  252.  
  253. clip_win(win,clip)
  254. register WINDOW *win;            /* window to restore to screen */
  255. register WINDOW *clip;            /* clip window */
  256.    {
  257.    int x0 = Max(W(x0),C(x0)) - W(x0);
  258.    int y0 = Max(W(y0),C(y0)) - W(y0);
  259.    int x1 = Min(W(x0)+BIT_WIDE(W(border)),C(x0)+BIT_WIDE(C(border))) - W(x0);
  260.    int y1 = Min(W(y0)+BIT_HIGH(W(border)),C(y0)+BIT_HIGH(C(border))) - W(y0);
  261.  
  262.    if (W(save) != (BITMAP *) 0) {
  263.  
  264. /*    ******* look at clipping region **********
  265.       bit_blit(W(border),x0,y0,x1-x0,y1-y0 ,
  266.                BIT_NOT(BIT_DST),W(save),x0,y0);
  267.       getchar();
  268. end of debug */
  269.  
  270.       bit_blit(W(border),x0,y0,x1-x0,y1-y0,
  271.                BIT_SRC,W(save),x0,y0);
  272.       }
  273.    else
  274.       if( debug )
  275.      fprintf(stderr,"clip: can't restore %s\r\n",W(tty));
  276. #ifdef DEBUG
  277.    dprintf(o)(stderr,"\t\t  restore %s (clip to %s)\r\n",W(tty),C(tty));
  278. #endif
  279.    }
  280.  
  281. /*****************************************************************************
  282.  *    restore a previously saved pixel image of the window 
  283.  */
  284.  
  285. restore_win(win)
  286. register WINDOW *win;            /* window to restore to screen */
  287.    {
  288.    if (W(save) != (BITMAP *) 0)
  289.    bit_blit(W(border),0,0,BIT_WIDE(W(border)),BIT_HIGH(W(border)),
  290.           BIT_SRC,W(save),0,0);
  291. #ifdef DEBUG
  292.    dprintf(o)(stderr,"\t\t  restoring %s\r\n",W(tty));
  293. #endif
  294.    }
  295.  
  296. /*****************************************************************************
  297.  *    move the mouse, keep exclusive control 
  298.  *    "how" specifies how we recognize completion:
  299.  *        how == 0:    all buttons were up at start of action,
  300.  *                any button pushed down completes the action.
  301.  *        how != 0:    some button was down at start of action,
  302.  *                all buttons released completes the action.
  303.  */
  304.  
  305. int
  306. move_mouse(screen,mouse,x,y,how)
  307. BITMAP *screen;
  308. int mouse, *x, *y;
  309. int how;
  310.    {
  311.    register int mx = *x, my = *y;
  312.    register int button = 0;
  313.    int dx,dy;
  314.    MOUSE_ON(mx,my);
  315.    do {
  316.       button=mouse_get(mouse,&dx,&dy);
  317.       MOUSE_OFF(mx,my);
  318.       mx += dx;
  319.       my -= dy;
  320.       mx = BETWEEN(0,mx,BIT_WIDE(screen)); 
  321.       my = BETWEEN(0,my,BIT_HIGH(screen)); 
  322.       MOUSE_ON(mx,my);
  323.       }
  324.    while (how ? button!= 0 : button==0);
  325.    if( how )
  326.     do_button( 0 );
  327.    MOUSE_OFF(mx,my);
  328.    *x = mx;
  329.    *y = my;
  330.    return(button);
  331.    }
  332.  
  333. /*****************************************************************************
  334.  *    parse a line into fields
  335.  */
  336.  
  337. #ifdef SYSV
  338. #define index        strchr
  339. #endif
  340.  
  341. #define iswhite(x)    (index(" \t",x))
  342.  
  343. int
  344. parse(line,fields)
  345. register char *line;
  346. register char **fields;
  347.    {
  348.    char *index();
  349.    int inword = 0;
  350.    int count = 0;
  351.    char *start;
  352.    register char c;
  353.  
  354.    for(start = line;(c = *line) && c != '\n';line++)
  355.       if (inword && iswhite(c)) {
  356.          inword = 0;
  357.          *line = '\0';
  358.          *fields++ = start;
  359.          count++;
  360.          }
  361.       else if (!inword && !iswhite(c)) {
  362.          start = line;
  363.          inword = 1;
  364.          }
  365.  
  366.    if (inword) {
  367.       *fields++ = start;
  368.       count++;
  369.       if (c == '\n')
  370.          *line = '\0';
  371.       }
  372.    *fields = (char *) 0;
  373.    return(count);
  374.    }
  375.  
  376. /*****************************************************************************
  377.  *    parse a string to interpret \'s
  378.  */
  379.  
  380. char *
  381. trans(s)
  382. char *s;
  383.    {
  384.    char *result = s;
  385.    register int i=0;
  386.    register char c;
  387.    register int got_slash=0;
  388.  
  389.    while(c = *s++&0x7f) {
  390.       if (got_slash){
  391.          switch(c) {
  392.             case 'e':
  393.             case 'E': result[i++] = '\033'; break;
  394.             case 'n': result[i++] = '\n';   break;
  395.             case 'r': result[i++] = '\r';   break;
  396.             case 'b': result[i++] = '\b';   break;
  397.             case 'f': result[i++] = '\f';   break;
  398.             case 'g': result[i++] = '\007'; break;
  399.             case 's': result[i++] = ' ';    break;
  400.             case '\\': result[i++] = '\\';  break;
  401.             case 'M': result[i++] = *s++|0x80; break;
  402.             default:  result[i++] = c;      break;
  403.             }
  404.          got_slash = 0;
  405.          }
  406.       else if (c=='\\')
  407.          got_slash++;
  408.       else 
  409.          result[i++] = c;
  410.       } 
  411.    result[i] = '\0';
  412.    return(result);
  413.    }
  414.  
  415. /* suspend MGR */
  416.  
  417. int suspend()
  418.    {
  419. #ifdef SIGSTOP
  420.    register WINDOW *win;
  421.  
  422.    MOUSE_OFF(mousex,mousey);
  423.    sleep(1);    /* give the key time to go up */
  424.    set_kbd(0);    /* fix up keyboard modes */
  425.  
  426.    for(win=active;win!=(WINDOW *) 0;win=win->next) {
  427.       killpg(W(pid),SIGSTOP);
  428.       if (W(flags)&W_ACTIVE)
  429.          save_win(win);
  430.       }
  431.  
  432.    reset_tty(0);
  433.    kbd_reset();
  434.    close(mouse);
  435.    reset_tty(0);
  436.    fprintf(stderr,"\fmgr suspended ...\n");
  437. #ifdef WHO
  438.    restore_utmp(0,"");
  439. #endif
  440.  
  441.    do_cmd( 's' );    /* do the suspention command */
  442.  
  443.    /* courtesy DVW */
  444.    signal(SIGTSTP, SIG_DFL);
  445.    kill(0,SIGTSTP);            /* send stop signal to self */
  446.    sleep(1);                /* wait for CONT signal */
  447.    signal(SIGTSTP, catch);
  448.  
  449.    if (set_kbd(1) != 0) {    /* reopen kbd (as 0) */
  450.       _quit();
  451.       fprintf(stderr,"Sorry, Can't reopen kbd\n");
  452.       exit(1);
  453.       }
  454.    mouse = mouse_reopen();
  455.    set_tty(0);
  456.    bell_on();    /* this resets the keyboard! */
  457.  
  458.    do_cmd( 'r' );    /* do the resumption command */
  459.  
  460. #ifdef WHO
  461.    save_utmp(ttyname(0));
  462. #endif
  463.    erase_win(screen,0,0);
  464.    if (active) {
  465.       for(win=ACTIVE(prev);win!=active;win=W(prev)) {
  466.          restore_win(win);
  467.          killpg(W(pid),SIGCONT);
  468.          }
  469.       restore_win(active);
  470.       killpg(ACTIVE(pid),SIGCONT);
  471.       }
  472. #endif
  473.    MOUSE_ON(mousex,mousey);
  474.    }
  475.  
  476. /*    Get a font from font numbers.
  477.     Font numbers run 0 through MAXFONT;
  478.     Font 0 is the default font. */
  479.  
  480. struct font *
  481. Get_font(fnt)
  482. int fnt;                /* font number */
  483.    {
  484.    struct font *new, *get_font();
  485.    char buff[MAX_PATH];
  486.    char *name;
  487.  
  488.    if (fnt<=0 || fnt>MAXFONT || fontlist[fnt-1] == (char *) 0)
  489.       return(font);
  490.  
  491.    if (*fontlist[fnt-1] == '/') 
  492.       name = fontlist[fnt-1];
  493.    else {
  494.       sprintf(buff, "%s/%s", font_dir, fontlist[fnt-1]);
  495.       name = buff;
  496.       }
  497.    if ((new = get_font(name))==(struct font *)0)
  498.       new = font;
  499.    else
  500.       new->ident = fnt;
  501.    return(new);
  502.    }
  503.  
  504. #ifdef ALIGN
  505.  
  506. /* align a window so a byte boundary occurs somewhere insode the border */
  507.   
  508. int
  509. alignwin(screen,x,dx,slop)
  510. register BITMAP *screen;
  511. register int *x, *dx;
  512. int slop;
  513.    {
  514.    register int adjust = (BIT_X(screen)+ *x) & 7;
  515.  
  516.    if (adjust>0 && adjust<(8-slop)) {
  517.       *x -= adjust;
  518. #ifdef DEBUG
  519.       dprintf(A)(stderr,"Adjusting x by %d",adjust);
  520. #endif
  521.       }
  522. #ifdef DEBUG
  523.       dprintf(A)(stderr," at [%d/%d]\r\n",*x,(*x)&7);
  524. #endif
  525.  
  526.    adjust = (adjust + *dx) &7;
  527.  
  528.    if (adjust>slop) { 
  529.       *dx += 8-adjust;
  530. #ifdef DEBUG
  531.       dprintf(A)(stderr,"Adjusting dx by %d\r\n",8-adjust);
  532. #endif
  533.       }
  534. #ifdef DEBUG
  535.       dprintf(A)(stderr," at [%d/%d]\r\n",*x + *dx,(*x + *dx)&7);
  536. #endif
  537.    }
  538. #endif ALIGN
  539.  
  540. /* look for and remove all references to a particular font */
  541.  
  542. int
  543. font_purge(gone)
  544. register struct font *gone;        /* invalid font pointer */
  545.    {
  546.    register WINDOW *win, *win2;
  547.    register int count=0;
  548.  
  549.    /* re-reference current window font */
  550.  
  551.    for(win=active;win != (WINDOW *) 0;win=win->next) {
  552.       if (W(font) == gone) {
  553.          W(font) = font;
  554.          count++;
  555.          }
  556.  
  557.       /* now re-reference any stacked fonts */
  558.  
  559.       for(win2=W(stack);win2 != (WINDOW *) 0;win2=win2->stack)
  560.          if (win2->font == gone) {
  561.             win2->font = font;
  562.             count++;
  563.             }
  564.       }
  565.    return(count);
  566.    }
  567.  
  568. /*********************************************************************/
  569.  
  570. /* make sure icon is valid */
  571.  
  572. int
  573. cursor_ok(map,x,y)
  574. BITMAP *map;            /* cursor icon */
  575. int x,y;                    /* starting coord */
  576.    {
  577.    if (map==BIT_NULL || BIT_WIDE(map) < 16+x  || BIT_HIGH(map) < 32+y)
  578.       return(0);
  579.    else                     /* we'll check more later */
  580.       return(1);
  581.    }
  582.  
  583.  
  584. static int cursoron = 0;
  585.  
  586. cursor_on()
  587. {
  588.     if( !active ) {
  589.         cursoron = 0;
  590.         return;
  591.     }
  592.     if( cursoron )
  593.         return;
  594.     do_cursor(active);
  595.     cursoron = 1;
  596. }
  597.  
  598. cursor_off()
  599. {
  600.     if( !active ) {
  601.         cursoron = 0;
  602.         return;
  603.     }
  604.     if( !cursoron )
  605.         return;
  606.     cursoron = 0;
  607.     do_cursor(active);
  608. }
  609.  
  610. static int
  611. do_cursor(win)
  612. WINDOW *win;
  613.     {
  614.     switch(W(curs_type)) {
  615.         case CS_BLOCK:
  616.             bit_blit(W(window), W(x)+W(text.x),
  617.                 W(y)+W(text.y)-W(font->head.high),
  618.                 W(font->head.wide), W(font->head.high),
  619.                 BIT_NOT(BIT_DST), 0, 0, 0);
  620.             break;
  621.         case CS_BOX:
  622.             bit_blit(W(window), W(x)+W(text.x),
  623.                 W(y)+W(text.y)-W(font->head.high)+1,
  624.                 W(font->head.wide), W(font->head.high)-2,
  625.                 BIT_NOT(BIT_DST), 0, 0, 0);
  626.             bit_blit(W(window), W(x)+W(text.x)-2,
  627.                 W(y)+W(text.y)-W(font->head.high)-1,
  628.                 W(font->head.wide)+4, W(font->head.high)+2,
  629.                 BIT_NOT(BIT_DST), 0, 0, 0);
  630.             break;
  631.         case CS_LEFT:
  632.             bit_blit(W(window), W(x)+W(text.x) - 1,
  633.                 W(y)+W(text.y)-W(font->head.high),
  634.                 2, W(font->head.high),
  635.                 BIT_NOT(BIT_DST), 0, 0, 0);
  636.             break;
  637.         case CS_RIGHT:
  638.             bit_blit(W(window), W(x)+W(text.x)+W(font->head.wide)-1,
  639.                 W(y)+W(text.y)-W(font->head.high),
  640.                 2, W(font->head.high),
  641.                 BIT_NOT(BIT_DST), 0, 0, 0);
  642.             break;
  643.         case CS_UNDER:
  644.             bit_blit(W(window), W(x)+W(text.x),
  645.                 W(y)+W(text.y)-1,
  646.                 W(font->head.wide), 2,
  647.                 BIT_NOT(BIT_DST), 0, 0, 0);
  648.             break;
  649.         }
  650.     }
  651.  
  652. /* system command - turn off root privaleges */
  653.  
  654. system(command)
  655. char *command;
  656. {
  657.         int status, pid, w;
  658.         register int (*istat)(), (*qstat)();
  659.  
  660.     if (!command  ||  *command == '\0')
  661.         return(0);
  662.         if ((pid = vfork()) == 0) { /* does vfork work? */
  663.  
  664.                 /* make sure commands doesn't run as root */
  665.       
  666.                 int uid = getuid();
  667.                 int gid = getgid();
  668.                 setreuid(uid,uid);
  669.                 setregid(gid,gid);
  670.  
  671.         close(0);
  672.         open("/dev/null",0);
  673.  
  674.                 execl("/bin/sh", "sh", "-c", command, 0);
  675.                 _exit(127);
  676.         }
  677.         istat = signal(SIGINT, SIG_IGN);
  678.         qstat = signal(SIGQUIT, SIG_IGN);
  679.         while ((w = wait(&status)) != pid && w != -1)
  680.                 ;
  681.         if (w == -1)
  682.                 status = -1;
  683.         signal(SIGINT, istat);
  684.         signal(SIGQUIT, qstat);
  685.         return(status);
  686. }
  687.